/*
 * Class
 * DistributionFactory
 */
package pl.abstractvoid.distributions;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;

/**
 * Represents the factory of distributions with random input parameter sets.
 * 
 * @author Wojciech Szałapski
 */
public class DistributionFactory {
    
    /**
     * List of all the available distributions.
     */
    private final static ArrayList<Class<? extends AbstractDistribution>> distributionsList =
            new ArrayList<>();
    
    static {
        distributionsList.add(DiscreteDistribution.class);
        distributionsList.add(NormalDistribution.class);
        distributionsList.add(PoissonDistribution.class);
        distributionsList.add(ExponentialDistribution.class);
        distributionsList.add(GeometricDistribution.class);
        distributionsList.add(BinomialDistribution.class);
        distributionsList.add(PascalDistribution.class);
        distributionsList.add(UniformDistribution.class);
        distributionsList.add(ChiSquaredDistribution.class);
        distributionsList.add(GammaDistribution.class);
        distributionsList.add(StudentDistribution.class);
    }
    
    /**
     * Returns an instance of a probability distribution of the given class with 
     * random parameters.
     * 
     * @param distributionClass Class of the distribution to get the instance of.
     * @return Distribution instance of the given class with random input 
     *         parameters.
     */
    public static AbstractDistribution getDistribution(
            Class<? extends AbstractDistribution> distributionClass) {
        try {
            return (AbstractDistribution) distributionClass.getMethod("getSampleDistributionData", (Class<?>[]) null).invoke(distributionClass, (Object[]) null);
        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException ex) {
            return null;
        }
    }

    /**
     * Returns the list of all the distributions available.
     * 
     * @return ArrayList of all the distributions available.
     */
    public static ArrayList<Class<? extends AbstractDistribution>> getDistributionsList() {
        return distributionsList;
    }
}
